package top.miay.snowid;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @description: snowid-generator.yaml配置映射类
 * @author 猿猿长成记
 */
public class SnowIdGeneratorConfig {
    /**
     * 数据中心数量
     * */
    private long dcCount = 1;
    /**
     * 支持处理的时钟回拨时长
     * */
    private int clockBackTime = 4;
    /**
     * snowid-generator元年
     * */
    private String epochTime = "2025-01-01 00:00:00";
    /**
     * 应用配置信息
     * */
    private AppInfo appInfo;

    public static class AppInfo{
        /**
         * 应用所属数据中心标识
         * */
        private DataCenter dataCenter = DataCenter.IDC_1;
        /**
         * 应用运行模式
         * */
        private RunMode runMode = RunMode.VM;
        /**
         * 默认以秒为时间戳
         * TODO 配置暂未生效，默认以秒为控制频率
         * */
        private TimeUnit timeUnit = TimeUnit.SECONDS;
        /**
         * 默认30位时间戳，可标识最大秒数2^30s 可持续使用约 34年
         * */
        private long timStampBits = 30;
        /**
         * 默认11位机器标识，最多标识1024台机器
         * 以6数据中心(三地六中心高规格，一般应用无法达到)单应用服务256，可满足多数服务使用
         * */
        private long machineIdBits = 11;
        /**
         * 默认22位序列号，可标识序列号至多2^22
         * 以秒为生成时间戳，可满足秒级TPS 400w+
         * 使用秒作为生成时间戳同时屏蔽了使用毫秒的单毫秒限制4096*1000的限制
         * */
        private long sequenceBits = 22;
        /**
         * 检查通过后设置的机器标识
         * */
        private long machineId;
        /**
         * 检查通过后设置的数据中心位数
         * */
        private long dcBits=0;
        /**
         * runMode=VM配置
         * */
        private VMConfig vmConfig;
        /**
         * runMode=K8S_CLOUD_STATEFUL_SET配置
         * */
        private K8sConfig k8sConfig;
        /**
         * 配置要生成的ID列表
         * */
        private List<Id> ids;

        public DataCenter getDataCenter() {
            return dataCenter;
        }

        public void setDataCenter(DataCenter dataCenter) {
            this.dataCenter = dataCenter;
        }

        public RunMode getRunMode() {
            return runMode;
        }

        public void setRunMode(RunMode runMode) {
            this.runMode = runMode;
        }

        public TimeUnit getTimeUnit() {
            return timeUnit;
        }

        public void setTimeUnit(TimeUnit timeUnit) {
            this.timeUnit = timeUnit;
        }

        public long getTimStampBits() {
            return timStampBits;
        }

        public void setTimStampBits(long timStampBits) {
            this.timStampBits = timStampBits;
        }

        public long getMachineIdBits() {
            return machineIdBits;
        }

        public void setMachineIdBits(long machineIdBits) {
            this.machineIdBits = machineIdBits;
        }

        public long getSequenceBits() {
            return sequenceBits;
        }

        public void setSequenceBits(long sequenceBits) {
            this.sequenceBits = sequenceBits;
        }

        public long getMachineId() {
            return machineId;
        }

        public void setMachineId(long machineId) {
            this.machineId = machineId;
        }

        public long getDcBits() {
            return dcBits;
        }

        public void setDcBits(long dcBits) {
            this.dcBits = dcBits;
        }

        public VMConfig getVmConfig() {
            return vmConfig;
        }

        public void setVmConfig(VMConfig vmConfig) {
            this.vmConfig = vmConfig;
        }

        public K8sConfig getK8sConfig() {
            return k8sConfig;
        }

        public void setK8sConfig(K8sConfig k8sConfig) {
            this.k8sConfig = k8sConfig;
        }

        public List<Id> getIds() {
            return ids;
        }

        public void setIds(List<Id> ids) {
            this.ids = ids;
        }

        @Override
        public String toString() {
            return "AppInfo{" +
                    "k8sConfig=" + k8sConfig +
                    ", dataCenter=" + dataCenter +
                    ", runMode=" + runMode +
                    ", timeUnit=" + timeUnit +
                    ", timStampBits=" + timStampBits +
                    ", machineIdBits=" + machineIdBits +
                    ", sequenceBits=" + sequenceBits +
                    ", machineId=" + machineId +
                    ", dcBits=" + dcBits +
                    ", vmConfig=" + vmConfig +
                    ", ids=" + ids +
                    '}';
        }
    }

    /**
     * Id配置类
     * */
    public static class Id{
        /**
         * ID名称
         * */
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    /**
     * runMode=VM机器信息配置
     * */
    public static class Machine{
        private String ip;
        private long machineId;

        public String getIp() {
            return ip;
        }

        public void setIp(String ip) {
            this.ip = ip;
        }

        public long getMachineId() {
            return machineId;
        }

        public void setMachineId(long machineId) {
            this.machineId = machineId;
        }

        @Override
        public String toString() {
            return "Machine{" +
                    "ip='" + ip + '\'' +
                    ", machineId=" + machineId +
                    '}';
        }
    }

    /**
     * 数据中心信息
     * */
    public static enum DataCenter{
        IDC_1("IDC_1", 0),
        IDC_2("IDC_2", 1),
        IDC_3("IDC_3", 2),
        IDC_4("IDC_4", 3),
        IDC_5("IDC_5", 4),
        IDC_6("IDC_6", 5),
        IDC_7("IDC_7", 6),
        IDC_8("IDC_8", 7);

        private String dataCenterName;
        private long dataCenterIndex;

        DataCenter(String dataCenterName, long dateCenterIndex){
            this.dataCenterName = dataCenterName;
            this.dataCenterIndex = dateCenterIndex;
        }

        public String getDataCenterName() {
            return dataCenterName;
        }

        public long getDataCenterIndex() {
            return dataCenterIndex;
        }
    }

    public enum RunMode{
        /**
         * 基于虚拟机部署应用，使用序列时需指定ip列表
         * */
        VM,
        /**
         * 基于k8sStatefulSet部署运行的应用，运行时需指定pod名称
         * */
        K8S_CLOUD_STATEFUL_SET;
    }

    /**
     * 机器IP地址类型、网卡名称、机器列表仅在appInfo.runMode=vm时使用
     * */
    public static class VMConfig{
        /**
         * machineIpType: 要获取的机器IP类型
         * */
        private IpType machineIpType = IpType.IPv4;
        /**
         * eth: 要获取的ip所在网卡，默认可不配置，多网卡情况下需配置
         * */
        private String eth;
        /**
         * machines: 所有机器信息列表，主要包括ip+id
         * */
        private List<Machine> machines;

        public IpType getMachineIpType() {
            return machineIpType;
        }

        public void setMachineIpType(IpType machineIpType) {
            this.machineIpType = machineIpType;
        }

        public String getEth() {
            return eth;
        }

        public void setEth(String eth) {
            this.eth = eth;
        }

        public List<Machine> getMachines() {
            return machines;
        }

        public void setMachines(List<Machine> machines) {
            this.machines = machines;
        }

        @Override
        public String toString() {
            return "VMConfig{" +
                    "machineIpType=" + machineIpType +
                    ", eth='" + eth + '\'' +
                    ", machines=" + machines +
                    '}';
        }
    }

    /**
     * podName、podNameEnvKey仅在appInfo.runMode=K8S_CLOUD_STATEFUL_SET时使用
     * */
    public static class K8sConfig{
        /**
         * podNameEnvKey: 指定k8s注入的pod名称的环境变量
         * */
        private String podNameEnvKey;
        /**
         * podName: 指定k8s pod名字
         * */
        private String podName;

        public String getPodNameEnvKey() {
            return podNameEnvKey;
        }

        public void setPodNameEnvKey(String podNameEnvKey) {
            this.podNameEnvKey = podNameEnvKey;
        }

        public String getPodName() {
            return podName;
        }

        public void setPodName(String podName) {
            this.podName = podName;
        }

        @Override
        public String toString() {
            return "K8sConfig{" +
                    "podNameEnvKey='" + podNameEnvKey + '\'' +
                    ", podName='" + podName + '\'' +
                    '}';
        }
    }

    public long getDcCount() {
        return dcCount;
    }

    public void setDcCount(long dcCount) {
        this.dcCount = dcCount;
    }

    public AppInfo getAppInfo() {
        return appInfo;
    }

    public void setAppInfo(AppInfo appInfo) {
        this.appInfo = appInfo;
    }

    public int getClockBackTime() {
        return clockBackTime;
    }

    public void setClockBackTime(int clockBackTime) {
        this.clockBackTime = clockBackTime;
    }

    public String getEpochTime() {
        return epochTime;
    }

    public void setEpochTime(String epochTime) {
        this.epochTime = epochTime;
    }

    @Override
    public String toString() {
        return "SnowIdGeneratorConfig{" +
                "dcCount=" + dcCount +
                ", clockBackTime=" + clockBackTime +
                ", appInfo=" + appInfo +
                '}';
    }
}
